/*!
 * \file WTSBaseDataMgr.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 基础数据管理实现类
 * 
 * \details 该文件定义了WonderTrader的基础数据管理类，负责：
 *          - 品种、合约、交易时段等基础数据的管理
 *          - 交易日历和节假日管理
 *          - 交易时间计算和边界处理
 *          - 数据加载和缓存
 */
#pragma once
#include "../Includes/IBaseDataMgr.h"
#include "../Includes/WTSCollection.hpp"
#include "../Includes/FasterDefs.h"

USING_NS_WTP;

/*!
 * \brief 交易日模板映射表
 * \details 使用高性能哈希表存储交易日模板数据，键为品种ID，值为交易日模板
 */
typedef faster_hashmap<ShortKey, TradingDayTpl>	TradingDayTplMap;

/*!
 * \brief 合约列表，使用高性能哈希表实现
 * \details 键为合约代码，值为合约信息
 */
typedef WTSHashMap<LongKey>		WTSContractList;

/*!
 * \brief 交易所合约映射表
 * \details 键为交易所代码，值为该交易所下的合约列表
 */
typedef WTSHashMap<ShortKey>	WTSExchgContract;

/*!
 * \brief 合约信息映射表
 * \details 键为合约代码，值为合约详细信息
 */
typedef WTSHashMap<LongKey>		WTSContractMap;

/*!
 * \brief 交易时段映射表
 * \details 键为时段ID，值为交易时段信息
 */
typedef WTSHashMap<ShortKey>		WTSSessionMap;

/*!
 * \brief 品种信息映射表
 * \details 键为品种ID，值为品种详细信息
 */
typedef WTSHashMap<ShortKey>		WTSCommodityMap;

/*!
 * \brief 交易时段品种映射表
 * \details 键为时段ID，值为该时段下的品种集合
 */
typedef faster_hashmap<ShortKey, CodeSet> SessionCodeMap;

/*!
 * \class WTSBaseDataMgr
 * \brief WonderTrader基础数据管理实现类
 * 
 * \details 基础数据管理类实现了IBaseDataMgr接口，提供以下核心功能：
 *          
 *          **基础数据管理**：
 *          - 品种信息管理（加载、查询、缓存）
 *          - 合约信息管理（加载、查询、缓存）
 *          - 交易时段管理（加载、查询、缓存）
 *          
 *          **交易日历管理**：
 *          - 交易日历加载和缓存
 *          - 节假日判断
 *          - 交易日计算
 *          
 *          **时间处理**：
 *          - 交易日期计算
 *          - 交易时间边界计算
 *          - 前后交易日计算
 *          
 * \note 该类是线程安全的，可以在多线程环境中使用
 * \see IBaseDataMgr, WTSCommodityInfo, WTSContractInfo, WTSSessionInfo
 */
class WTSBaseDataMgr : public IBaseDataMgr
{
public:
	/*!
	 * \brief 构造函数
	 * \details 初始化基础数据管理器的内部数据结构
	 */
	WTSBaseDataMgr();

	/*!
	 * \brief 析构函数
	 * \details 清理内部数据结构和资源
	 */
	~WTSBaseDataMgr();

public:
	/*!
	 * \brief 根据标准品种ID获取品种信息
	 * \param stdPID 标准品种ID
	 * \return 品种信息对象指针，如果不存在则返回NULL
	 */
	virtual WTSCommodityInfo*	getCommodity(const char* stdPID) override;

	/*!
	 * \brief 根据交易所和品种ID获取品种信息
	 * \param exchg 交易所代码
	 * \param pid 品种ID
	 * \return 品种信息对象指针，如果不存在则返回NULL
	 */
	virtual WTSCommodityInfo*	getCommodity(const char* exchg, const char* pid) override;

	/*!
	 * \brief 根据合约代码获取合约信息
	 * \param code 合约代码
	 * \param exchg 交易所代码，默认为空
	 * \return 合约信息对象指针，如果不存在则返回NULL
	 */
	virtual WTSContractInfo*	getContract(const char* code, const char* exchg = "") override;

	/*!
	 * \brief 获取指定交易所的所有合约列表
	 * \param exchg 交易所代码，默认为空表示所有交易所
	 * \return 合约信息数组，调用者负责释放内存
	 */
	virtual WTSArray*			getContracts(const char* exchg = "") override;

	/*!
	 * \brief 根据时段ID获取交易时段信息
	 * \param sid 时段ID
	 * \return 交易时段信息对象指针，如果不存在则返回NULL
	 */
	virtual WTSSessionInfo*		getSession(const char* sid) override;

	/*!
	 * \brief 根据合约代码获取对应的交易时段信息
	 * \param code 合约代码
	 * \param exchg 交易所代码，默认为空
	 * \return 交易时段信息对象指针，如果不存在则返回NULL
	 */
	virtual WTSSessionInfo*		getSessionByCode(const char* code, const char* exchg = "") override;

	/*!
	 * \brief 获取所有交易时段信息
	 * \return 交易时段信息数组，调用者负责释放内存
	 */
	virtual WTSArray*			getAllSessions() override;

	/*!
	 * \brief 判断指定日期是否为节假日
	 * \param stdPID 标准品种ID
	 * \param uDate 日期，格式为YYYYMMDD
	 * \param isTpl 是否使用模板判断，默认为false
	 * \return 如果是节假日返回true，否则返回false
	 */
	virtual bool				isHoliday(const char* stdPID, uint32_t uDate, bool isTpl = false) override;

	/*!
	 * \brief 计算交易日期
	 * \param stdPID 标准品种ID
	 * \param uDate 日期，格式为YYYYMMDD
	 * \param uTime 时间，格式为HHMMSS
	 * \param isSession 是否使用交易时段判断，默认为false
	 * \return 交易日期，格式为YYYYMMDD
	 */
	virtual uint32_t			calcTradingDate(const char* stdPID, uint32_t uDate, uint32_t uTime, bool isSession = false) override;

	/*!
	 * \brief 获取交易时间边界
	 * \param stdPID 标准品种ID
	 * \param tDate 交易日期，格式为YYYYMMDD
	 * \param isSession 是否使用交易时段判断，默认为false
	 * \param isStart 是否获取开始时间，默认为true
	 * \return 交易时间边界，格式为YYYYMMDDHHMMSS
	 */
	virtual uint64_t			getBoundaryTime(const char* stdPID, uint32_t tDate, bool isSession = false, bool isStart = true) override;

	/*!
	 * \brief 释放内部资源
	 * \details 清理所有缓存的数据和内部数据结构
	 */
	void		release();

	/*!
	 * \brief 加载交易时段配置
	 * \param filename 配置文件路径
	 * \param isUTF8 是否使用UTF8编码，默认为false
	 * \return 加载是否成功
	 */
	bool		loadSessions(const char* filename, bool isUTF8);

	/*!
	 * \brief 加载品种配置
	 * \param filename 配置文件路径
	 * \param isUTF8 是否使用UTF8编码，默认为false
	 * \return 加载是否成功
	 */
	bool		loadCommodities(const char* filename, bool isUTF8);

	/*!
	 * \brief 加载合约配置
	 * \param filename 配置文件路径
	 * \param isUTF8 是否使用UTF8编码，默认为false
	 * \return 加载是否成功
	 */
	bool		loadContracts(const char* filename, bool isUTF8);

	/*!
	 * \brief 加载节假日配置
	 * \param filename 配置文件路径
	 * \return 加载是否成功
	 */
	bool		loadHolidays(const char* filename);

public:
	/*!
	 * \brief 获取交易日期
	 * \param stdPID 标准品种ID
	 * \param uOffDate 日期偏移，默认为0
	 * \param uOffMinute 分钟偏移，默认为0
	 * \param isTpl 是否使用模板，默认为false
	 * \return 交易日期，格式为YYYYMMDD
	 */
	uint32_t	getTradingDate(const char* stdPID, uint32_t uOffDate = 0, uint32_t uOffMinute = 0, bool isTpl = false);

	/*!
	 * \brief 获取下一个交易日
	 * \param stdPID 标准品种ID
	 * \param uDate 当前日期，格式为YYYYMMDD
	 * \param days 偏移天数，默认为1
	 * \param isTpl 是否使用模板，默认为false
	 * \return 下一个交易日，格式为YYYYMMDD
	 */
	uint32_t	getNextTDate(const char* stdPID, uint32_t uDate, int days = 1, bool isTpl = false);

	/*!
	 * \brief 获取上一个交易日
	 * \param stdPID 标准品种ID
	 * \param uDate 当前日期，格式为YYYYMMDD
	 * \param days 偏移天数，默认为1
	 * \param isTpl 是否使用模板，默认为false
	 * \return 上一个交易日，格式为YYYYMMDD
	 */
	uint32_t	getPrevTDate(const char* stdPID, uint32_t uDate, int days = 1, bool isTpl = false);

	/*!
	 * \brief 判断是否为交易日
	 * \param stdPID 标准品种ID
	 * \param uDate 日期，格式为YYYYMMDD
	 * \param isTpl 是否使用模板，默认为false
	 * \return 如果是交易日返回true，否则返回false
	 */
	bool		isTradingDate(const char* stdPID, uint32_t uDate, bool isTpl = false);

	/*!
	 * \brief 设置交易日
	 * \param stdPID 标准品种ID
	 * \param uDate 日期，格式为YYYYMMDD
	 * \param isTpl 是否使用模板，默认为false
	 */
	void		setTradingDate(const char* stdPID, uint32_t uDate, bool isTpl = false);

	/*!
	 * \brief 获取交易时段的品种集合
	 * \param sid 时段ID
	 * \return 品种集合指针，如果不存在则返回NULL
	 */
	CodeSet*	getSessionComms(const char* sid);

private:
	/*!
	 * \brief 根据品种ID获取模板ID
	 * \param stdPID 标准品种ID
	 * \return 模板ID
	 */
	const char* getTplIDByPID(const char* stdPID);

private:
	/*!
	 * \brief 交易日模板映射表
	 * \details 存储每个品种的交易日模板信息
	 */
	TradingDayTplMap	m_mapTradingDay;

	/*!
	 * \brief 交易时段品种映射表
	 * \details 存储每个交易时段下的品种集合
	 */
	SessionCodeMap		m_mapSessionCode;

	/*!
	 * \brief 交易所合约映射表
	 * \details 存储每个交易所下的合约列表
	 */
	WTSExchgContract*	m_mapExchgContract;

	/*!
	 * \brief 交易时段映射表
	 * \details 存储所有交易时段信息
	 */
	WTSSessionMap*		m_mapSessions;

	/*!
	 * \brief 品种信息映射表
	 * \details 存储所有品种信息
	 */
	WTSCommodityMap*	m_mapCommodities;

	/*!
	 * \brief 合约信息映射表
	 * \details 存储所有合约信息
	 */
	WTSContractMap*		m_mapContracts;
};

